package com.moonshineproject.plugin.project.view
{
	import com.moonshineproject.GlobalEventDispatcher;
	import com.moonshineproject.IDEModel;
	import com.moonshineproject.editor.BasicTextEditor;
	import com.moonshineproject.plugin.project.event.TreeMenuItemEvent;
	import com.moonshineproject.plugin.project.vo.FileWrapper;
	import com.moonshineproject.plugin.templating.TemplatingHelper;
	import com.moonshineproject.plugin.templating.event.RequestTemplatesEvent;
	
	import flash.display.NativeMenu;
	import flash.display.NativeMenuItem;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.filesystem.File;
	import flash.filters.GlowFilter;
	import flash.ui.ContextMenu;
	import flash.ui.Keyboard;
	
	import mx.binding.utils.ChangeWatcher;
	import mx.controls.treeClasses.TreeItemRenderer;
	import mx.core.UIComponent;
	import mx.core.mx_internal;
	
	import spark.components.Label;
	import spark.components.TextInput;

	use namespace mx_internal;
	
	public class FTETreeItemRenderer extends TreeItemRenderer
	{
		private var label2:Label;
		private var editText:TextInput;
		
		private var model:IDEModel;
		private var isOpenIcon:Sprite;
		private var hitareaSprite:Sprite;
		private var sourceControlBackground:UIComponent;
		private var sourceControlText:Label;
		private var sourceControlSystem:Label;
		
		public function FTETreeItemRenderer()
		{
			super();
			model = IDEModel.getInstance();
			ChangeWatcher.watch(model, 'activeEditor', onActiveEditorChange);
		}
		
		private function onActiveEditorChange(event:Event):void
		{
			invalidateDisplayList();
		}
		
		public function startEdit():void
		{
			label2.visible = false;
			
			editText = new TextInput();
			editText.x = label2.x;
			editText.y = -2;
			editText.width = width;
			editText.height = height+4;
			editText.styleName = 'uiText';
			editText.setStyle('fontSize', 12);
			editText.setStyle('focusAlpha', 0);
			editText.setStyle('color', 0xe0e0e0);
			editText.setStyle('paddingTop', 3);
			editText.setStyle('contentBackgroundAlpha', 0);
			editText.setStyle('focusedTextSelectionColor', 0x2f0727);
			
			editText.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
			editText.addEventListener(FocusEvent.FOCUS_OUT, handleFocusOut);
			
			editText.text = label2.text;
			
			addChild(editText);
			
			editText.setFocus();
			
			// Normally you don't want to change the file ending
			if (editText.text.indexOf(".") > -1)
			{
				editText.selectRange(0, editText.text.indexOf("."));
			} 
		}
		
		public function stopEdit():void
		{
			editDone();
		}
		
		public function cancelEdit():void
		{
			if (!editText) return;
			
			label2.visible = true;
			editText.removeEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
			editText.removeEventListener(FocusEvent.FOCUS_OUT, handleFocusOut);
			
			removeChild(editText);
			editText = null;
		}
		
		protected function handleKeyDown(event:KeyboardEvent):void
		{
			if (event.charCode == Keyboard.ENTER)
			{
				editDone();
			}
			else if (event.charCode == Keyboard.ESCAPE)
			{
				editCancel();
			}
		}
		
		protected function handleFocusOut(event:Event):void
		{
			editDone();
		}
		
		protected function editDone():void
		{
			dispatchEvent( new TreeMenuItemEvent(TreeMenuItemEvent.EDIT_END, editText.text, FileWrapper(data)) );
			cancelEdit();
			
			data = data;
		}
		
		protected function editCancel():void
		{
			dispatchEvent( new TreeMenuItemEvent(TreeMenuItemEvent.EDIT_CANCEL, editText.text, FileWrapper(data)) );
			cancelEdit();
		}
		
		override public function set data(value:Object):void
		{
			super.data = value;
			
			var fw:FileWrapper = value as FileWrapper;
			if (fw)
			{
				contextMenu = new ContextMenu();
				
				var open:NativeMenuItem = new NativeMenuItem('Open');
				open.addEventListener(Event.SELECT, redispatch);
	   			contextMenu.addItem(open);
				
				var newMenu:NativeMenuItem = new NativeMenuItem('New');
				newMenu.submenu = new NativeMenu();
				contextMenu.addItem(newMenu);
				newMenu.addEventListener(Event.DISPLAYING, populateTemplatingMenu);
				
				if (fw.sourceController)
				{
					contextMenu.addItem( fw.sourceController.getTreeRightClickMenu(fw.file) );
				}
				
				if (!fw.isRoot)
				{
					var rename:NativeMenuItem = new NativeMenuItem('Rename');
					rename.addEventListener(Event.SELECT, redispatch);
					contextMenu.addItem(rename);
					
	   				contextMenu.addItem(new NativeMenuItem(null, true));
	   				
	   				var del:NativeMenuItem = new NativeMenuItem('Delete');
	   				del.addEventListener(Event.SELECT, redispatch);
	   				contextMenu.addItem(del)
	   				
	   				contextMenu.addItem(new NativeMenuItem(null, true));
				}
				
				var refresh:NativeMenuItem = new NativeMenuItem('Refresh');
				refresh.addEventListener(Event.SELECT, redispatch); 
				contextMenu.addItem(refresh);
				
				
				if (fw.isRoot)
				{
					contextMenu.addItem(new NativeMenuItem(null, true));
					
	   				var settings:NativeMenuItem = new NativeMenuItem('Settings');
	   				settings.addEventListener(Event.SELECT, redispatch);
	   				contextMenu.addItem(settings);
	   				var close:NativeMenuItem = new NativeMenuItem('Close');
	   				close.addEventListener(Event.SELECT, redispatch);
	   				contextMenu.addItem(close);
				}
				
				
				//contextMenu.addEventListener(Event.SELECT, redispatch);
			}
			
			isOpenIcon.visible = false;
		}
		
		private function populateTemplatingMenu(e:Event):void
		{
			var menuItem:NativeMenuItem = e.target as NativeMenuItem;
			menuItem.submenu = new NativeMenu();
			
			var event:RequestTemplatesEvent = new RequestTemplatesEvent();
			GlobalEventDispatcher.getInstance().dispatchEvent(event);
			
			for each (var file:File in event.fileTemplates)
			{
				var label:String = TemplatingHelper.getTemplateLabel(file);
				var item:NativeMenuItem = new NativeMenuItem(label);
				item.data = file;
				item.addEventListener(Event.SELECT, redispatch);
				menuItem.submenu.addItem(item);
			}
			
			var folder:NativeMenuItem = new NativeMenuItem('Folder');
			folder.addEventListener(Event.SELECT, redispatch);
			menuItem.submenu.addItem(folder);
		}
		
		private function redispatch(event:Event):void
		{
			var type:String = NativeMenuItem(event.target).label;
			if (type == "New") return;
			
			
			var e:TreeMenuItemEvent = new TreeMenuItemEvent(TreeMenuItemEvent.RIGHT_CLICK_ITEM_SELECTED, 
															type, 
															FileWrapper(data));
			e.renderer = this;
			if (event.target.data)
			{
				e.menuLabel = "New File";
				e.extra = event.target.data;	
			}
			
			dispatchEvent(e);
		}
		
		override protected function createChildren():void
		{
			super.createChildren();
			
			isOpenIcon = new Sprite();
			isOpenIcon.mouseEnabled = false;
			isOpenIcon.mouseChildren = false;
			isOpenIcon.graphics.clear();
			isOpenIcon.graphics.beginFill(0xe15fd5);
			isOpenIcon.graphics.drawCircle(1, 7, 2);
			isOpenIcon.graphics.endFill();
			isOpenIcon.visible = false;
			var glow:GlowFilter = new GlowFilter(0xff00e4, .4, 6, 6, 2);
			isOpenIcon.filters = [glow];
			addChild(isOpenIcon);
			
			sourceControlBackground = new UIComponent();
			sourceControlBackground.mouseEnabled = false;
			sourceControlBackground.mouseChildren = false;
			sourceControlBackground.visible = false;
			sourceControlBackground.graphics.beginFill(0x484848, .9);
			sourceControlBackground.graphics.drawRect(0, -2, 30, 17);
			sourceControlBackground.graphics.endFill();
			sourceControlBackground.graphics.lineStyle(1, 0x0, .3);
			sourceControlBackground.graphics.moveTo(-1, -2);
			sourceControlBackground.graphics.lineTo(-1, 16);
			sourceControlBackground.graphics.lineStyle(1, 0xEEEEEE, .1);
			sourceControlBackground.graphics.moveTo(0, -2);
			sourceControlBackground.graphics.lineTo(0, 16);
			addChild(sourceControlBackground);
			
			// For drawing SVN/GIT/HG/CVS etc
			sourceControlSystem = new Label();
			sourceControlSystem.width = 30;
			sourceControlSystem.height = 16;
			sourceControlSystem.mouseEnabled = false;
			sourceControlSystem.mouseChildren = false;
			sourceControlSystem.styleName = 'uiText';
			sourceControlSystem.setStyle('fontSize', 10);
			sourceControlSystem.setStyle('color', 0xe0e0e0);
			sourceControlSystem.setStyle('textAlign', 'center');
			sourceControlSystem.setStyle('paddingTop', 3);
			sourceControlSystem.maxDisplayedLines = 1;
			sourceControlSystem.visible = false;
			addChild(sourceControlSystem);
			
			// For displaying source control status
			sourceControlText = new Label();
			sourceControlText.width = 20;
			sourceControlText.height = 16;
			sourceControlText.mouseEnabled = false;
			sourceControlText.mouseChildren = false;
			sourceControlText.styleName = 'uiText';
			sourceControlText.setStyle('fontSize', 9);
			sourceControlText.setStyle('color', 0xcdcdcd);
			sourceControlText.setStyle('textAlign', 'center');
			sourceControlText.setStyle('paddingTop', 3);
			sourceControlText.maxDisplayedLines = 1;
			sourceControlText.visible = false;
			addChild(sourceControlText);
			
			
			hitareaSprite = new Sprite();
			hitArea = hitareaSprite;
			addChild(hitareaSprite);
		}
		
		override mx_internal function createLabel(childIndex:int):void
	    {
	        super.createLabel(childIndex);
	        label.visible = false;
	        
	        if (!label2)
			{	
				label2 = new Label();
				label2.mouseEnabled = false;
				label2.mouseChildren = false;
				label2.styleName = 'uiText';
				label2.setStyle('fontSize', 12);
				label2.setStyle('color', 0xe0e0e0);
				label2.maxDisplayedLines = 1;
				
				if (childIndex == -1) 
					addChild(label2);
				else 
					addChildAt(label2, childIndex);
			}
	    }
		
	    override mx_internal function removeLabel():void
	    {
	    	super.removeLabel();
	    	
	        if (label2 != null)
	        {
	            removeChild(label2);
	            label2 = null;
	        }
	    }
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    	{
        	super.updateDisplayList(unscaledWidth, unscaledHeight);
        	
        	hitareaSprite.graphics.clear();
        	hitareaSprite.graphics.beginFill(0x0, 0);
        	hitareaSprite.graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
        	hitareaSprite.graphics.endFill();
        	hitArea = hitareaSprite;
        	
        	// Draw our own FTE label
        	label2.width = label.width;
        	label2.height = label.height;
			label2.x = label.x;
        	label2.y = label.y+5;
        	
        	label2.text = label.text;
        	
        	if (label) label.visible = false;
        	
        	// Show lil' dot if we are the currently opened file
        	if (model.activeEditor is BasicTextEditor
        		&& BasicTextEditor(model.activeEditor).currentFile)
        	{
				if (data.nativePath
					&& data.nativePath == BasicTextEditor(model.activeEditor).currentFile.nativePath)
        		{
        			isOpenIcon.visible = true;
        			isOpenIcon.x = label2.x-8;
        		}
        		else isOpenIcon.visible = false;
        	}
        	else isOpenIcon.visible = false;
        	
        	// Update source control status
        	sourceControlSystem.visible = false;
        	sourceControlText.visible = false;
        	sourceControlBackground.visible = false;
        	
        	if (data.sourceController)
        	{
        		if (data.isRoot)
        		{
	        		// Show source control system name (SVN/CVS/HG/GIT)
	        		sourceControlSystem.text = FileWrapper(data).sourceController.systemNameShort; 
	        		
	        		sourceControlBackground.visible = true;
	        		sourceControlSystem.visible = true;
	        		
	        		sourceControlBackground.x = unscaledWidth-30;
	        		sourceControlSystem.x = sourceControlBackground.x;
	        		sourceControlSystem.y = label2.y;	
        		}
        		else
        		{
        			var st:String = data.sourceController.getStatus(data.nativePath);
	        		if (st)
	        		{
	        			sourceControlText.text = st;
	        			sourceControlBackground.visible = true;
	        			sourceControlText.visible = true;
	        			
	        			sourceControlBackground.x = unscaledWidth-20;
	        			sourceControlText.x = sourceControlBackground.x;
	        			sourceControlText.y = label2.y;
	        		}	
        		}
        	}
		} // updateDisplayList
		
	}
}